﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using DevExpress.XtraGrid;
using DevExpress.XtraGrid.Views.Grid;
using DevExpress.XtraGrid.Views.Base;
using DevExpress.XtraGrid.Columns;
using DevExpress.XtraEditors.Repository;
using DevExpress.XtraEditors.Controls;
using DevExpress.XtraTab;
using DevExpress.XtraTab.ViewInfo;

using NJUST.AUTO06.DBORM.DBEntity.MODEL;
using NJUST.AUTO06.DBORM.DBEntity.BLL;

using NJUST.AUTO06.Utility;

using HZK.Helper;
using HZK.CustomConfig;

namespace HZK.UI.SY
{
    /// <summary>
    /// 用户管理模块
    /// </summary>
    public partial class FormSYUser : Form
    {
        public FormSYUser()
        {
            InitializeComponent();
        }

        // 用户信息
        BindingList<User> userList  = null;
        // 查询用户信息
        BindingList<User> queryList = null;
        // 工具栏的按钮集合
        List<ToolStripButton> tsButton = new List<ToolStripButton>();
        // 字段中英文显示信息
        List<ItemEx> showNameList = new List<ItemEx>();

        /// <summary>
        /// 配置Combobox控件的内容
        /// </summary>
        private void ConfigComboBoxContent()
        {
            // GridControl中嵌入“用户部门”复选框
            RepositoryItemComboBox cbxUserDept = new RepositoryItemComboBox();
            cbxUserDept.Items.Clear();

            // 读取相应字段信息
            List<string> typeList = GetTypes("部门分类");
            if (typeList.Count > 1)
            {
                // 下拉框加入条目信息
                cbxUserDept.Items.AddRange(typeList.ToArray());
                // 设置选项只能选择不能编辑
                cbxUserDept.TextEditStyle = TextEditStyles.DisableTextEditor;

                // 关联到表格列
                gvUser.Columns["UserDept"].ColumnEdit = cbxUserDept;
            }

            // GridControl中嵌入“用户权限”信息
            RepositoryItemComboBox cbxUserRole = new RepositoryItemComboBox();

            // 下拉框加入条目信息
            cbxUserRole.Items.Clear();
            cbxUserRole.Items.AddRange(new string[] { "普通用户", "管理员" });

            if (PropertyHelper.CurrentUser.UserRole == "超级管理员") 
            {
                cbxUserRole.Items.Add("系统管理员");//超级管理员有增加系统管理员的权限
            }

            // 设置选项只能选择不能编辑
            cbxUserRole.TextEditStyle = TextEditStyles.DisableTextEditor;

            // 关联到表格列
            gvUser.Columns["UserRole"].ColumnEdit = cbxUserRole;
        }

        /// <summary>
        /// 界面加载初始化
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void FormSYUser_Load(object sender, EventArgs e)
        {
            try 
            {
                // 从数据库查询用户信息,生成绑定数据集

                List<User> userItems = null;

                if(PropertyHelper.CurrentUser.UserRole == "超级管理员")
                {
                    // 查询所有用户信息
                    userItems = UserBLL.Instance.Find("*", "");
                }

                if (PropertyHelper.CurrentUser.UserRole == "系统管理员")
                {
                    // 查询所有管理员和普通用户信息
                    userItems = UserBLL.Instance.FindCommonUsers();
                }

                // 绑定表格显示
                userList = new BindingList<User>(userItems);
            }
            catch(Exception ex)
            {
                MessageUtil.ShowWarning(ex.Message);
                return;
            }
            
            // 设置表格数据源
            gcUser.DataSource = userList;
            // 默认无焦点
            gvUser.FocusedRowHandle = -1;

            // 配置表格嵌入的Combobox控件
            ConfigComboBoxContent();

            // 用户列表的标题栏显示名
            List<string> showName = new List<string>();
            showName.AddRange(new string[] { "登录名称", "用户姓名", "登录密码", "用户部门", "用户权限" });

            User userNameCfg = new User();

            int index = 0;
            foreach (System.Reflection.PropertyInfo p in userNameCfg.GetType().GetProperties())
            {
                ItemEx item = new ItemEx(p.Name, showName[index]); // 中文显示和数据库字段名

                // 加入下拉列表
                cbxCondition.Items.Add(item);
                // 保存字段映射
                showNameList.Add(item);

                index++;
            }

            // 默认为空
            cbxCondition.SelectedIndex = -1;
            // 默认为模糊查询
            cbxQueryWay.SelectedIndex = 0;            

            //// 表格绑定数据源里的所有字段生成列
            //gvUser.PopulateColumns();
            //// 列宽自适应表格内容
            //gvUser.BestFitColumns();

            tsButton.Add(toolAdd);
            tsButton.Add(toolEdit);
            tsButton.Add(toolDelete);
            tsButton.Add(toolSave);
            tsButton.Add(toolCancel);

            toolStrip1.Tag = "SAVED";
        }

        #region 辅助函数

        /// <summary>
        /// 根据标题确定某一分类中的所有条目
        /// </summary>
        /// <param name="caption"></param>
        /// <returns></returns>
        private List<string> GetTypes(string caption)
        {
            List<string> typeList = new List<string>();
            
            // 查找ComboBox是否对应可配置字段
            List<FieldType> Items = PropertyHelper.FieldTypeItems.Where<FieldType>(item => item.FieldTypeName == caption)
                                                                                .OrderBy(item => item.FieldTypeSerialNo)
                                                                                .ToList<FieldType>();
            // 加入配置信息
            if (Items.Count != 0)
            {
                foreach (FieldType item in Items)
                {
                    typeList.Add(item.FieldTypeValue);
                }        
            }

            return typeList;                                               
        }

        #endregion

        #region 工具栏操作

        /// <summary>
        /// 工具栏的“新增”操作
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toolAdd_Click(object sender, EventArgs e)
        {
            this.gcUser.DataSource = userList;

            // 表格中新增一行可编辑行
            gvUser.AddNewRow();
            gvUser.OptionsBehavior.Editable = true;  // 行可编辑
            gvUser.ShowEditor();                     // 显示光标

            // 在档案已保存的情况下，才能再次新增档案
            if (toolStrip1.Tag.ToString() == "SAVED")
            {
                // 设置工具栏按键状态
                UIHelper.Instance.SetToolButtonStatus(tsButton);
            }

            // 设置当前状态为“新增”
            toolStrip1.Tag = "ADD";
        }

        /// <summary>
        /// 工具栏的“编辑”操作
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toolEdit_Click(object sender, EventArgs e)
        {
            if (gvUser.GetSelectedRows().Count() == 0)
            {
                MessageUtil.ShowWarning("请选择要修改的用户信息！");
                return;
            }

            // 在档案已保存的情况下，才能修改档案
            if (toolStrip1.Tag.ToString() == "SAVED")
            {
                // 表格选中的记录
                User item = (User)gvUser.GetFocusedRow();

                if (item.UserRole == "管理员" | item.UserRole == "系统管理员" && (PropertyHelper.CurrentUser.UserRole != "超级管理员") && PropertyHelper.CurrentUser.UserRole != "系统管理员")
                {
                    MessageUtil.ShowWarning("“管理员”用户不能修改“admin”超级用户信息！");
                    return;
                }

                // 使能表格可编辑
                gvUser.OptionsBehavior.Editable = true;
                gvUser.ShowEditor();

                gvUser.Columns["UserCode"].OptionsColumn.AllowEdit = false; // 用户登录名不允许编辑
                gvUser.Columns["Password"].OptionsColumn.AllowEdit = false; // 密码不允许编辑

                // 设置工具栏按键状态
                UIHelper.Instance.SetToolButtonStatus(tsButton);
            }

            // 设置当前状态为“编辑”
            toolStrip1.Tag = "EDIT";
        }

        /// <summary>
        /// 工具栏的“删除”操作
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toolDelete_Click(object sender, EventArgs e)
        {
            // 是否选中条目
            int[] selected = gvUser.GetSelectedRows();
            if (selected.Length == 0)
            {
                MessageUtil.ShowWarning("请选择要删除的用户信息！");
                return;
            }

            // 表格选中的记录
            User item = (User)gvUser.GetFocusedRow();

            // 不能删除管理员用户admin
            if (item.UserRole == "系统管理员")
            {
                MessageUtil.ShowWarning("不能删除用户名为“admin”的系统管理员！");
                return;
            }

            string str = string.Format("确实要删除该用户信息吗？");
            if (DialogResult.OK == MessageUtil.ShowTips(str))
            {
                selected.Reverse();

                foreach (int rowIndex in selected)
                {
                    // 表格中删除选中的列
                    User user = (User)gvUser.GetRow(rowIndex);
                    gvUser.DeleteRow(rowIndex);

                    try
                    {
                        // 在数据库中删除用户和权限信息
                        UserBLL.Instance.DeleteUser(user.UserCode);
                    }
                    catch(Exception ex)
                    {
                        MessageUtil.ShowWarning(ex.Message);

                        return;
                    }                 
                }

                MessageUtil.ShowTips("删除成功！");
            }
        }

        /// <summary>
        /// 工具栏的“保存”操作
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toolSave_Click(object sender, EventArgs e)
        {
            // 表格信息尚未保存
            gcUser.Tag = "BeforeSave"; // 否则即使信息完整也会引发行验证失败
            // 更新关联数据源
            gvUser.PostEditor();
            // 不用按回车或者点击另一个单元格就能保存编辑中的单元格内容
            gvUser.CloseEditor();

            if (!gvUser.UpdateCurrentRow()) return;

            // 表格禁止编辑
            gvUser.OptionsBehavior.Editable = false;

            // 数据库操作
            SaveUser();
        }

        /// <summary>
        /// 工具栏的“取消”操作
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toolCancel_Click(object sender, EventArgs e)
        {
            toolStrip1.Tag = "SAVED";

            //  取消表格编辑状态
            gvUser.OptionsBehavior.Editable = false;
            gvUser.CancelUpdateCurrentRow();

            // 设置工具栏按键状态
            UIHelper.Instance.SetToolButtonStatus(tsButton);
        }

        /// <summary>
        /// 全数据集查询
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toolAllQuery_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(cbxCondition.Text))
            {
                MessageUtil.ShowWarning("查询条件不能为空！");
                return;
            }

            // 确定字段的本名
            //List<ItemEx> userField = showNameList.Where<ItemEx>(item => item.Text == cbxCondition.SelectedItem.ToString()).ToList<ItemEx>();

            // 从数据库查询用户信息
            string cmdText = LinqHelper.Instance.BuildQueryCondition((string)((ItemEx)cbxCondition.SelectedItem).Tag, txtKeyWord.Text, cbxQueryWay.Text);
            queryList = new BindingList<User>(UserBLL.Instance.Find("*", cmdText));

            // 表格关联数据集
            gcUser.DataSource = queryList;
            // 自适应列宽
            gvUser.BestFitColumns();

            if (queryList.Count == 0)
            {
                MessageUtil.ShowTips("没有查询到相关用户信息！");
            }
        }

        /// <summary>
        /// 工具栏的“退出”操作
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toolExit_Click(object sender, EventArgs e)
        {
            XtraTabPage page = (XtraTabPage)this.Parent;
            XtraTabControl tcMainUI = (XtraTabControl)page.Parent;

            UIHelper.Instance.CloseTabPage(tcMainUI, page);
        }

        #endregion

        #region 数据库操作

        private bool ValidateUser(string userCode)
        {
            // 确定用户是否存在
            User userTemp = UserBLL.Instance.FindByID(userCode);
            if(userTemp != null)
            {
                return false;
            }

            return true;
        }

        /// <summary>
        /// 保存用户信息
        /// </summary>
        private void SaveUser()
        {
            // 获取当前列信息
            User user = (User)gvUser.GetFocusedRow();

            if(user == null)
            {
                MessageUtil.ShowWarning("对象为空！");
                return;
            }
            
            if (toolStrip1.Tag.ToString() == "ADD")
            {
                AddNewUser(user);
            }

            if (toolStrip1.Tag.ToString()== "EDIT")
            {
                UpdateUser(user);                
            }

            toolStrip1.Tag     = "SAVED";
            gcUser.Tag         = "SAVED";

            // 设置工具栏按键状态
            UIHelper.Instance.SetToolButtonStatus(tsButton);
        }

        /// <summary>
        /// 添加新用户
        /// </summary>
        /// <param name="user">用户对象</param>
        public void AddNewUser(User user)
        {
            if (ValidateUser(user.UserCode) == false)
            {
                MessageUtil.ShowWarning("用户名已存在！");
                return;
            }

            // 创建用户权限表
            List<UserRight> userRights = GetUserRight(user.UserRole, user.UserCode);
            // 事务添加用户和权限表
            try
            {
                UserBLL.Instance.AddNewUser(user, userRights);
            }
            catch (Exception ex)
            {
                MessageUtil.ShowWarning(ex.ToString());
                return;
            }

            MessageUtil.ShowTips("添加用户和用户权限信息成功！");
        }

        /// <summary>
        /// 更新用户
        /// </summary>
        /// <param name="user">用户对象</param>
        public void UpdateUser(User user)
        {
            if (user == null) return;

            try
            {
                if(UserBLL.Instance.Update(user, user.UserCode) > 0)
                {
                    MessageUtil.ShowTips("更新成功!");
                }
            }
            catch (Exception ex)
            {
                MessageUtil.ShowWarning(ex.Message);
            }
        }

        #endregion

        #region 用户权限

        /// <summary>
        /// 根据用户名和用户角色获得默认权限信息表
        /// </summary>
        /// <param name="userRole">用户角色</param>
        /// <param name="userCode">用户名</param>
        /// <returns></returns>
        private List<UserRight> GetUserRight(string userRole, string userCode)
        {
            List<UserRight> newUserRight = new List<UserRight>();

            // 用户权限表在配置文件中的所在节
            SettingsCollection moduleCollection = new SettingsCollection();

            if (userRole == "普通用户")
            {
                moduleCollection = CustomConfigHelper.Instance.GetMember<SettingsCollection>("CommonUser");
            }
            else if (userRole == "管理员") // 管理员
            {
                moduleCollection = CustomConfigHelper.Instance.GetMember<SettingsCollection>("AdminUser");
            }
            else //系统管理员
            {
                moduleCollection = CustomConfigHelper.Instance.GetMember<SettingsCollection>("SysAdminUser");
            }

            for (int i = 0; i < moduleCollection.Count; i++)
            {
                UserRight right = new UserRight();

                right.UserCode = userCode;
                right.ModuleTag = moduleCollection[i].Tag;
                right.ModuleName = moduleCollection[i].Name;
                right.IsRight = moduleCollection[i].IsRight == "1" ? true : false;

                if (right.IsRight == true) // 如果该模块有权限，则默认对所有的工具按钮有权限，可在“权限设置”中修改
                {
                    right.EnabledType = "编辑;查询;输入;输出;控制";
                }
                else
                {
                    right.EnabledType = "";
                }

                // 用户权限写入数据集
                newUserRight.Add(right);
            }

            return newUserRight;
        }

        #endregion     

        #region 表格事件响应

        /// <summary>
        /// 行失去焦点时触发本事件，进行表格行数据的效验
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void gvUserInfo_ValidateRow(object sender, ValidateRowEventArgs e)
        {
            if (toolStrip1.Tag.ToString() == "ADD" || toolStrip1.Tag.ToString() == "EDIT")
            {
                // 在“新增”或“修改”模式时，处理行失去焦点事件

                // 当前行的内容转换成类对象
                GridView gv = sender as GridView;
                User userItem = (User)gv.GetFocusedRow();

                // 保存未填信息的单元格
                List<string> nullCells = new List<string>(); 

                // 利用反射属性遍历类的成员变量，查找是否有空字段
                foreach (System.Reflection.PropertyInfo p in userItem.GetType().GetProperties())
                {
                    if (string.IsNullOrEmpty((string)p.GetValue(userItem, null)))
                    {
                        // 用户部门可以为空，其他则记录下来
                        if ((string)p.Name != "UserDept") 
                        {
                            nullCells.Add(showNameList.Where(g => g.Tag.ToString() == p.Name).ToList()[0].Text);
                        }
                    }
                }

                if (nullCells.Count != 0)
                {
                    // 行数据校验不正确，触发InvalidRowException事件
                    e.Valid = false;
                    // 提示不能为空的字段
                    e.ErrorText = string.Format("{0}不能为空", string.Join(",", nullCells.ToArray()));
                }
                else if((string)gcUser.Tag != "BeforeSave")
                {
                    // 行数据校验不正确，触发InvalidRowException事件
                    e.Valid = false;
                    // 提示用户修改但未保存
                    e.ErrorText = "是否保存当前用户信息？";
                }
            }
        }

        /// <summary>
        /// 当行数据检查失败触发此事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void gvUserInfo_InvalidRowException(object sender, InvalidRowExceptionEventArgs e)
        {
            e.ExceptionMode = ExceptionMode.NoAction; // 不显示自带的提示

            if (e.ErrorText == "是否保存当前用户信息？")
            {
                DialogResult result = MessageUtil.ShowYesNoCancelAndTips(e.ErrorText);

                if (result == DialogResult.Yes)
                {
                    // 表格信息尚未保存
                    gcUser.Tag = "BeforeSave"; // 否则即使信息完整也会引发行验证失败
                    // 更新关联数据源
                    gvUser.PostEditor();
                    // 不用按回车或者点击另一个单元格就能保存编辑中的单元格内容
                    gvUser.CloseEditor();

                    if (!gvUser.UpdateCurrentRow()) return;

                    // 表格禁止编辑
                    gvUser.OptionsBehavior.Editable = false;

                    // 保存用户信息
                    SaveUser();
                }
                else if (result == DialogResult.No)
                {
                    toolStrip1.Tag = "SAVED";

                    //  取消表格编辑状态
                    gvUser.OptionsBehavior.Editable = false;
                    gvUser.CancelUpdateCurrentRow();

                    // 设置工具栏按键状态
                    UIHelper.Instance.SetToolButtonStatus(tsButton);
                }

                // 如果是取消或是关闭对话框，则继续编辑该条档案
                gvUser.ShowEditor();
            }
            else
            {
                MessageUtil.ShowWarning(e.ErrorText);
                // 使能表格编辑
                gvUser.ShowEditor();
            }           
        }

        /// <summary>
        /// 定义单元格显示模式--密码框用“*”
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void gvUserInfo_CustomColumnDisplayText(object sender, CustomColumnDisplayTextEventArgs e)
        {
            if (e.Column.FieldName == "Password")
            {
                if (e.Value != null && e.Value.ToString().Length > 0)
                {
                    e.DisplayText = new string('*', 6);
                }
            }
        }

        #endregion

    }
}
